<cfparam name="resetFilters" default="false">
<cfparam name="showStats" default="false" />
<cfset isFiltered = false />
<cfset queryParams = StructNew() />

<!--- Program years --->
<cfif NOT IsDefined("client.gds.programYears") or resetFilters>
	<cfset client.gds.programYears = request.currentProgramYear>
<cfelseif IsDefined("filterProgramYears")>
	<cfset client.gds.programYears = filterProgramYears>
</cfif>
<cfif client.gds.programYears neq request.currentProgramYear>
	<cfset isFiltered = true />
	<cfset queryParams.programYears = client.gds.programYears />
<cfelse>
	<cfset queryParams.programYears = request.currentProgramYear />
</cfif>
<!--- Match Criteria --->
<cfif NOT IsDefined("client.gds.Match_Criteria") or resetFilters>
	<cfset client.gds.Match_Criteria = "1">
<cfelseif IsDefined("filterMatchCriteria")>
	<cfset client.gds.Match_Criteria = filterMatchCriteria>
</cfif>
<cfif client.gds.Match_Criteria neq "1">
	<cfset isFiltered = true />
	<cfset queryParams.Match_Criteria = client.gds.Match_Criteria />
</cfif>
<!--- Organizations --->
<cfif NOT IsDefined("client.gds.organizationIDs") or resetFilters>
	<cfset client.gds.organizationIDs = "All">
<cfelseif IsDefined("filterOrganizationIDs")>
	<cfset client.gds.organizationIDs = filterOrganizationIDs>
</cfif>
<cfif client.gds.organizationIDs neq "All">
	<cfset isFiltered = true />
	<cfset queryParams.organizationIDs = client.gds.organizationIDs />
	<cfset filterRegionIDs = "All" />
</cfif>
<!--- Regions --->
<cfif IsUserInRole("Super User")>
	<cfif NOT IsDefined("client.gds.regionIDs") or resetFilters>
		<cfset client.gds.regionIDs = "All">
	<cfelseif IsDefined("filterRegionIDs")>
		<cfset client.gds.regionIDs = filterRegionIDs>
	</cfif>
<cfelseif IsUserInRole("Regional Admin")>
	<cfset client.gds.regionIDs = request.authUser.regionID>
</cfif>
<cfif client.gds.regionIDs neq "All">
	<cfset isFiltered = true />
	<cfset queryParams.regionIDs = client.gds.regionIDs />
</cfif>
<!--- Proposal Value --->
<cfif NOT IsDefined("client.gds.proposalValue") or resetFilters>
	<cfset client.gds.proposalValue = "Unmatch">
<cfelseif IsDefined("filterProposalValue")>
	<cfset client.gds.proposalValue = filterProposalValue>
</cfif>
<cfif client.gds.proposalValue neq "All">
	<cfset isFiltered = true />
	<!--- <cfset queryParams.proposalValue = client.gds.proposalValue /> --->
</cfif>

<cfwddx action="cfml2wddx" input="#queryParams#" output="client.gds.queryParamsWDDX" />

<cfscript>
	base = new assets.calgrants.com.Base();
	organizationGateway = new assets.calgrants.com.gateway.OrganizationGateway();
	organizations = organizationGateway.query(regionIDs = IIf(IsUserInRole("Regional Admin"), request.authUser.regionID, ""), Organization_ID = IIf(IsUserInRole("Organizer") OR IsUserInRole("Site Contact"), request.authUser.organizationID, ""));
	storedProcedureGateway = new assets.calgrants.com.gateway.StoredProcedureGateway();
	regions = storedProcedureGateway.call("getDistinctRegions");
	gdsGateway = new assets.calgrants.com.gateway.GDSGateway();
	gds = gdsGateway.query(argumentCollection = queryParams);
</cfscript>

<h3>GDS<cfif isFiltered> <small><em>filtered</em></small></cfif></h3>

<cfoutput>
 
	<div class="row-fluid" style="margin-bottom: 10px;">
		<div class="span12">
			<a id="filterLink" href="##" class="btn" onclick="toggleFilter('filter')">Show filters</a>
			<span class="pull-right"><strong>Count:</strong> #gds.RecordCount#</span>
		</div>
	</div>
	
	<cfform name="gdsForm" id="gdsForm" action="#script_name#" method="post">
		<cfinput type="hidden" name="view" value="#view#">
		
		<div id="filter" class="alert alert-info alert-block" style="display: none;">
			<h4>Filters</h4>
			<table cellpadding="6">
				<tr valign="top">
					<td>
						<label>Program Year</label>
						<cfselect name="filterProgramYears" size="1" multiple="false" required="yes" message="Program Year filter is required" style="width: 150px;">
							<cfloop index="y" from="2012" to="#ListFirst(application.currentProgramYear, '-')#">
								<cfset py = "#y#-" & y+1>
								<option value="#py#"<cfif client.gds.programYears eq py> selected</cfif>>#py#</option>
							</cfloop>
						</cfselect>
					</td>
					<cfif IsUserInRole("Super User")>
						<td>
							<label>Region</label>
							<cfselect name="filterRegionIDs" size="7" multiple="true" required="yes" message="Region filter is required" style="width: 150px;">
								<option value="All"<cfif client.gds.regionIDs eq "All"> selected</cfif>>All</option>
								<cfloop query="regions">
									<option value="#Region_ID#"<cfif ListFind(client.gds.regionIDs, Region_ID)> selected</cfif>>#Region_ID#</option>
								</cfloop>
							</cfselect>
						</td>
					</cfif>
					<td>
						<label>Organizations</label>
						<cfselect name="filterOrganizationIDs" size="7" multiple="true" required="yes" message="Organizations filter is required" style="width: auto;">
							<option value="All"<cfif client.gds.organizationIDs eq "All"> selected</cfif>>All</option>
							<cfloop query="organizations">
								<option value="#Organization_ID#"<cfif ListFind(client.gds.organizationIDs, Organization_ID)> selected</cfif>>#Organization# - #City#</option>
							</cfloop>
						</cfselect>
					</td>
					<td>
						<label>Match Criteria</label>
						<cfselect name="filterMatchCriteria" size="1" required="yes" message="Match Criteria filter is required" style="width: 150px;">
							<!--- <option value="All"<cfif client.gds.matchCriteria eq "All"> selected</cfif>>All</option> --->
							<cfloop list="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20" index="matchCriteria">
								<option value="#matchCriteria#"<cfif ListFind(client.gds.Match_Criteria, matchCriteria)> selected</cfif>>#matchCriteria#</option>
							</cfloop>
						</cfselect>
					</td>
					<td>
						<label>Propsal Value</label>
						<cfselect name="filterProposalValue" size="1" required="yes" message="Proposal Value filter is required" style="width: 150px;">
							<option value="All"<cfif client.gds.proposalValue eq "All"> selected</cfif>>All</option>
							<cfloop list="Match,Review,Unmatch" index="proposalValue">
								<option value="#proposalValue#"<cfif ListFind(client.gds.proposalValue, proposalValue)> selected</cfif>>#proposalValue#</option>
							</cfloop>
						</cfselect>
					</td>
				</tr>
				<tr>
					<td colspan="5">
						<button type="submit" class="btn btn-info">Apply</button> <a href="#script_name#?view=#view#&resetFilters=true" class="btn btn-info">Clear</a>
					</td>
				</tr>
			</table>
		</div>
	</cfform>

</cfoutput>

<!--- <cfscript>
	// These two functions were moved to Base.cfc
	/********************************************************************************************************
	Compare Structs

	Arguments
		struct1				Struct that is the basis for comparison or master struct. All the properties in struct1 will be compared regardless of what's in struct2
		struct2				Struct containing comparison values. Missing properties will score 0 and extra properties will be ignored.
		config				Struct containing configuration for each comparison/scoring of each property in struct1 and struct2
			<property>..n		Each property in struct1 has a corresponding property in config, that is also a struct
				multiplier			Integer that weights the score for a property relative to the other properties on any scale
				maxOffset			Pass through to string comparison function
					
	Returns struct
		<property>..n		Each property in struct1 is returned as a struct including the values returned from the string comparison
			string1				Value for s1 with highlights
			string2				Value for s2 with highlights
			lcs					Longest common string
			distance			Average string length minus the longest string
			score				Distance divided by len of lcs
			weightedScore		Score multiplied by config.multiplier
			multiplier			Passed back from config.multiplier for reference
		maxScore			Maximum score possible - equal to the number of properties
		maxWeightedScore	Maximum score possible with multipliers
		totalScore			Sum of scores from all properties
		totalWeightedScore	Sum of scores from all properies with multipliers
	********************************************************************************************************/
	/*
	function compareStructs(struct1, struct2, config) {
		var return_struct = structNew();
		return_struct.struct1 = struct1;
		return_struct.struct2 = struct2;
		return_struct.config = config;
		return_struct.result = structNew();
		for (prop in struct1) {
			return_struct.result[prop] = compareStrings(arguments.struct1[prop], arguments.struct2[prop], arguments.config[prop].maxOffset);
		}
		return return_struct;	
	}
	*/
	
	/********************************************************************************************************
	Compare Strings
	
	Arguments
		string1		First string to be compared
		string2		Second string to be compared
		maxOffset	Maximum number of characters to look ahead in comparing strings
					
	Returns struct
		string1		Value for string1 with highlights
		string2		Value for string2 with highlights
		lcs			Longest common string within maxOffset
		distance	Average string length minus the longest string
		score		Distance divided by len of lcs
	********************************************************************************************************/
	/*
	function compareStrings(string1, string2, maxOffset) {
		var c = 0;
		var offset1 = 0;
		var offset2 = 0;
		var lcs = 0;
		// These two strings will contain the "highlighted" version
		var _string1 = createObject("java", "java.lang.StringBuffer").init(javacast("int", len(string1)*3));
		var _string2 = createObject("java", "java.lang.StringBuffer").init(javacast("int", len(string2)*3));
		// These characters will surround differences in the strings 
		// (Inserted into _string1 and _string2)
		var h1 = "<span class='hl'>";
		var h2 = "</span>";
		//var h1 = "";
		//var h2 = "";
		var return_struct = structNew();
		// If both strings are empty 
		if (not len(trim(string1)) and not len(trim(string2)))
			{	
				return_struct.lcs = 0;
				return_struct.score = 0;
				return_struct.distance = 0;
				return_struct.string1 = "";
				return_struct.string2 = "";
				return return_struct;
			}
		// If string2 is empty, but string1 isn't
		if (len(trim(string1)) and not len(trim(string2)))
			{
				return_struct.lcs = 0;
				return_struct.score = 0;
				return_struct.distance = len(string1);
				return_struct.string1 = h1 & string1 & h2;
				return_struct.string2 = "";
				return return_struct;
			}
		// If string1 is empty, but string2 isn't
		else if (len(trim(string2)) and not len(trim(string1)))
			{
				return_struct.lcs = 0;
				return_struct.score = 0;
				return_struct.distance = len(string2);
				return_struct.string1 = "";
				return_struct.string2 = h1 & string2 & h2;
				return return_struct;
			}
			
		// Examine the strings, one character at a time, ending at the shortest string
		// The offset adjusts for extra characters in either string.
		while ((c + offset1 lt len(string1))
			   and (c + offset2 lt len(string2)))
		{
			// Pull the next charactes out of string1 anbd string2
			next_string1 = mid(string1, c + offset1+1, iif(not c, 3, 1)); // First time through check the first three
			next_string2 = mid(string2, c + offset2+1, iif(not c, 3, 1)); // First time through check the first three
			// If they are equal
			if (compare(next_string1, next_string2) eq 0)
				{
					// Our longeset Common String just got one bigger
					lcs = lcs + 1;
					// Append the characters onto the "highlighted" version
					_string1.append(left(next_string1, 1));
					_string2.append(left(next_string2, 1));
				}
			// The next two charactes did not match
			// Now we will go into a sub-loop while we attempt to 
			// find our place again.  We will only search as long as
			// our maxOffset allows us to.
			else
				{
					// Don't reset the offsets, just back them up so you 
					// have a point of reference
					old_offset1 = offset1;
					old_offset2 = offset2;
					_string1_deviation = "";
					_string2_deviation = "";
					// Loop for as long as allowed by our offset 
					// to see if we can match up again
					for (i = 0; i lt maxOffset; i=i+1)
					{
						next_string1 = mid(string1, c + offset1 + i+1, 3); // Increments each time through.
						len_next_string1 = len(next_string1);
						bookmarked_string1 = mid(string1, c + offset1+1, 3); // stays the same
						next_string2 = mid(string2,c + offset2 + i+1,3); // Increments each time through.
						len_next_string2 = len(next_string2);
						bookmarked_string2 = mid(string2, c + offset2+1, 3); // stays the same
						
						// If we reached the end of both of the strings
						if(not len_next_string1 and not len_next_string2)
							{
								// Quit
								break;
							}
						// These variables keep track of how far we have deviated in the
						// string while trying to find our match again.
						_string1_deviation = _string1_deviation & left(next_string1, 1);
						_string2_deviation = _string2_deviation & left(next_string2, 1);
						// It looks like string1 has a match down the line which fits
						// where we left off in string2
						if (compare(next_string1 ,bookmarked_string2) eq 0)
							{
								// string1 is now offset THIS far from string2
								offset1 =  offset1+i;
								// Our longeset Common String just got bigger
								lcs = lcs + 1;
								// Now that we match again, break to the main loop
								break;
							}
							
						// It looks like string2 has a match down the line which fits
						// where we left off in string1
						if (compare(next_string2, bookmarked_string1) eq 0)
							{
								// string2 is now offset THIS far from string1
								offset2 = offset2+i;
								// Our longeset Common String just got bigger
								lcs = lcs + 1;
								// Now that we match again, break to the main loop
								break;
							}
					}
					//This is the number of inserted characters were found
					added_offset1 = offset1 - old_offset1;
					added_offset2 = offset2 - old_offset2;
					
					// We reached our maxoffset and couldn't match up the strings
					if(added_offset1 eq 0 and added_offset2 eq 0)
						{
							_string1.append(h1 & left(_string1_deviation, added_offset1+1) & h2);
							_string2.append(h1 & left(_string2_deviation, added_offset2+1) & h2);
						}
					// string2 had extra characters
					else if(added_offset1 eq 0 and added_offset2 gt 0)
						{
							_string1.append(left(_string1_deviation, 1));
							_string2.append(h1 & left(_string2_deviation, added_offset2) & h2 & right(_string2_deviation, 1));
						}
					// string1 had extra characters
					else if(added_offset1 gt 0 and added_offset2 eq 0)
						{
							_string1.append(h1 & left(_string1_deviation, added_offset1) & h2 & right(_string1_deviation, 1));
							_string2.append(left(_string2_deviation, 1));
						}
				}
			c=c+1;	
		}
		// Anything left at the end of string1 is extra
		if(c + offset1 lt len(string1))
			{
				_string1.append(h1 & right(string1, len(string1)-(c + offset1)) & h2);
			}
		// Anything left at the end of string2 is extra
		if(c + offset2 lt len(string2))
			{
				_string2.append(h1 & right(string2, len(string2)-(c + offset2)) & h2);
			}
			
		// Distance is the average string length minus the longest common string
		distance = (len(string1) + len(string2))/2 - lcs;
		// Longest string
		maxLen = iif(len(string1) gt len(string2), de(len(string1)), de(len(string2)));
		// Similarity is the distance divided by the max length
		score = iif(maxLen eq 0, 1, 1-(distance/maxLen));
		// Return what we found.
		return_struct.lcs = lcs;
		return_struct.score = score;
		return_struct.distance = distance;
		return_struct.string1 = _string1.toString(); // "highlighted" version
		return_struct.string2 = _string2.toString(); // "highlighted" version
		return return_struct;
	}
	*/
</cfscript> --->

<style>
	p.recID {
		margin-top: 20px;
	}
	span.highlighted {
		background-color: green;
		color: white;
		
	}
	span.hl {
		background-color: white;
		color: grey;
	}
	table.score-table td {
		width: 100%;
	}
	table.stat-table td, table.stat-table th {
		font-size: 0.7em;
		padding: 2px 4px;
	}
</style>

<cfif gds.RecordCount gt 0>

	<script type="text/javascript">
		var unmatchGDS = function(gdsId) {
			$.ajax({
				type: "GET",
				url: "/assets/calgrants/com/API.cfc?method=destroy",
				data: $.param({objType: "GDS", GDS_ID: gdsId}),
				success: function(response) {
					$("#gdsMatch_" + gdsId).slideUp("slow");
				},
				error: function(jqXHR, textStatus, errorThrown) {
					alert("Something went wrong. Please contact the developer");
				}
			});
		}
		var confirmUnmatch = function(gdsId) {
			if (confirm("Are you sure you want to remove this match\?")) {
				unmatchGDS(gdsId);
			}
		}
	</script>
	<cfscript>
		displayedCount = 0;
	</cfscript>
	<div class="container-fluid">
		<cfloop query="gds">
			<cfscript>
				// GDS
				gdsStruct = structNew();
				//gdsStruct.Student_ID = Student_ID;
				gdsStruct.First_Name = Replace(REReplace(UCase(Trim(First_Name)), "[^A-Z\ \-\']", "", "all"), "  ", " ", "all");
				gdsStruct.Last_Name = Replace(REReplace(UCase(Trim(Last_Name)), "[^A-Z\ \-\']", "", "all"), "  ", " ", "all");
				//gdsStruct.Full_Name = gdsStruct.First_Name & " " & gdsStruct.Last_Name;
				gdsStruct.Address = Replace(REReplace(UCase(Trim(Address)), "[^A-Z0-9\ ]", "", "all"), "  ", " ", "all");
				gdsStruct.City = Replace(REReplace(UCase(Trim(City)), "[^A-Z\ ]", "", "all"), "  ", " ", "all");
				gdsStruct.Zip_Code = Left(REReplace(Trim(Zip_Code), "[^0-9]", "", "all"), 5);
				//gdsStruct.Full_Address = gdsStruct.Address & " " & gdsStruct.City & " " & gdsStruct.Zip_Code;
				gdsStruct.Email = REReplace(UCase(Trim(Email)), "[^A-Z0-9\@\.\_\-]", "", "all");
				gdsStruct.SSN = Right(REReplace(Trim(SSN), "[^0-9]", "", "all"), 4);
				// Student
				studentStruct = structNew();
				//studentStruct.Student_ID = Student_ID;
				studentStruct.First_Name = Replace(REReplace(UCase(Trim(Student_First_Name)), "[^A-Z\ \-\']", "", "all"), "  ", " ", "all");
				studentStruct.Last_Name = Replace(REReplace(UCase(Trim(Student_Last_Name)), "[^A-Z\ \-\']", "", "all"), "  ", " ", "all");
				//studentStruct.Full_Name = studentStruct.First_Name & " " & studentStruct.Last_Name;
				studentStruct.Address = Replace(REReplace(UCase(Trim(Student_Address)), "[^A-Z0-9\ ]", "", "all"), "  ", " ", "all");
				studentStruct.City = Replace(REReplace(UCase(Trim(Student_City)), "[^A-Z\ ]", "", "all"), "  ", " ", "all");
				studentStruct.Zip_Code = Left(REReplace(Trim(Student_Zip_Code), "[^0-9]", "", "all"), 5);
				//studentStruct.Full_Address = studentStruct.Address & " " & studentStruct.City & " " & studentStruct.Zip_Code;
				studentStruct.Email = REReplace(UCase(Trim(Student_Email)), "[^A-Z0-9\@\.\_\-]", "", "all");
				studentStruct.SSN = Right(REReplace(Trim(Student_SSN), "[^0-9]", "", "all"), 4);
				if (isDate(DOB)) {
					gdsStruct.DOB = DateFormat(DOB, "mm/dd/yyyy");
				} else {
					gdsStruct.DOB = "";
				}
				if (isDate(Student_DOB)) {
					studentStruct.DOB = DateFormat(Student_DOB, "mm/dd/yyyy");
				} else {
					studentStruct.DOB = "";
				}
				gdsStruct.Phone1 = REReplace(Trim(Phone), "[^0-9]", "", "all");
				studentStruct.Phone1 = REReplace(Trim(Student_Phone1), "[^0-9]", "", "all");
				gdsStruct.Phone2 = REReplace(Trim(Phone), "[^0-9]", "", "all");	
				studentStruct.Phone2 = REReplace(Trim(Student_Phone2), "[^0-9]", "", "all");
				
				// Do the comparison! struct1 is GDS, struct2 is Student
				compareResult = base.compareStructs(gdsStruct, studentStruct);
				// create pointer variables for brevity of code
				result = compareResult.result;
				gds = compareResult.struct1;
				student = compareResult.struct2;
				config = compareResult.config;
				/* 
					GDS has one phone, Student has two.
					The comparison created properties for both combinations: GDS.Phone vs Student.Phone1 and GDS.Phone vs Student.Phone2.
					Keep the best match score, eliminate the other from scoring.
					
					- if Phone2 score is equal to or better than Phone1, create a Phone property and set it to result for Phone2
					- otherwise create Phone property and set it to result of Phone1
					- delete Phone1 and Phone2 properties (in all 4 structs) so they aren't scored down the line
				*/
				if (result.phone2.score gte result.phone1.score) {
					result.phone = result.phone2;
					gds.phone = gds.phone2;
					student.phone = student.phone2;
					config.phone = config.phone2;
				} else {
					result.phone = result.phone1;
					gds.phone = gds.phone1;
					student.phone = student.phone1;
					config.phone = config.phone1;
				}
				// delete Phone1 and Phone2 properties in result, struct1, struct2 and config
				StructDelete(result, "phone1");
				StructDelete(gds, "phone1");
				StructDelete(student, "phone1");
				StructDelete(config, "phone1");
				StructDelete(result, "phone2");
				StructDelete(gds, "phone2");
				StructDelete(student, "phone2");
				StructDelete(config, "phone2");

				try {
					/* wip - refactor algorithm*/
					compareResult.stats = structNew();
					stats = compareResult.stats;
					stats.scores = 0;
					//stats.offsets = 0;
					stats.lcss = 0;
					stats.distances = 0;
					stats.perfectCount = 0;
					stats.bonusCount = 0;
					stats.scoredCount = 0;
					stats.unscoredCount = 0;
	
					for (prop in result) {
						if (len(trim(gds[prop])) gt 0 and len(trim(student[prop])) gt 0) {
							stats.scores = stats.scores + result[prop].score;
							//stats.offsets = stats.offsets + result[prop].maxOffset;
							stats.lcss = stats.lcss + result[prop].lcs;
							stats.distances = stats.distances + result[prop].distance;
							if (result[prop].score eq 1) {
								stats.perfectCount = stats.perfectCount + 1;
								if (prop eq "address" or prop eq "email" or prop eq "phone") {
									stats.bonusCount = stats.bonusCount + 1;
								}
							}
							stats.scoredCount = stats.scoredCount + 1;
						} else {
							stats.unscoredCount = stats.unscoredCount + 1;	
						}
					}
					if (stats.scoredCount gte 1) {
						stats.scoresPct = stats.scores/stats.scoredCount * 100;
						stats.perfectsPct = stats.perfectCount/stats.scoredCount * 100;
					} else {
						stats.scoresPct = 0;
						stats.perfectsPct = 0;
					}
					if (stats.distances gte 1) {
						stats.lcssDistancesPct = stats.lcss/stats.distances * 100;
					} else if (stats.scoredCount gt 0) {
						stats.lcssDistancesPct = 100;
					} else {
						stats.lcssDistancesPct = 0;
					}
	
					/*
					sumOfScores = 0;
					sumOfOffsets = 0;
					sumOfLCS = 0;
					sumOfDistance = 0;
					perfectMatchCount = 0;
					perfectMatchBonusCount = 0;
					scoredCount = 0;
					unscoredCount = 0;
					for (prop in compareResult.result) {
						// if values exist for the property in both objects
						if (len(trim(compareResult.struct1[prop])) gt 0 and len(trim(compareResult.struct2[prop])) gt 0) {
							sumOfScores = sumOfScores + compareResult.result[prop].score; // perfect score is 1
							sumOfOffsets = sumOfOffsets + compareResult.config[prop].maxOffset;
							sumOfLCS = sumOfLCS + compareResult.result[prop].lcs;
							sumOfDistance = sumOfDistance + compareResult.result[prop].distance;
							if (compareResult.result[prop].score eq 1) {
								perfectMatchCount = perfectMatchCount + 1;
								if (prop eq "address" or prop eq "email" or prop eq "phone" or prop eq "phone1" or prop eq "phone2") {
									perfectMatchBonusCount = perfectMatchBonusCount + 1;
								}
							}
							scoredCount = scoredCount + 1;
						} else {
							unscoredCount = unscoredCount + 1;
						}
					}
					if (scoredCount gt 0) {
						score = sumOfScores/scoredCount * 100;
						if (sumOfDistance gt 0) {
							lcsDistanceScore = sumOfLCS/sumOfDistance;
						} else {
							lcsDistanceScore = sumOfLCS;
						}
						lcsDistancePct = lcsDistanceScore * 100;
						perfectPct = perfectMatchCount/scoredCount * 100;
						perfectBonusCount = perfectMatchCount + perfectMatchBonusCount;
						perfectBonusPct = perfectBonusCount/scoredCount * 100;
					} else {
						score = 0;
						lcsDistanceScore = 0;
						lcsDistancePct = 0;
						perfectPct = 0;
						perfectBonusCount = 0;
						perfectBonusPct = 0;
					}
					sumOfPercentages = score + lcsDistancePct + perfectPct + perfectBonusPct;
					perfectDiff = perfectMatchBonusCount - perfectMatchCount;
					proposalValue = "Error";
					proposalSource = "";
					*/
					/* scoring algorithm
					
					Unmatch
						perfectDiff = 0 && sumOfPercentages < 200
					
					Review
						perfectDiff > 0
	
					Auto match
						perfectDiff >= 2 (2 complex perfect matches)
						perfectDiff > 0 && score >= 70 && lcsDistancePct >= 100 && perfectPct >= 60
						score gte 90
						lcsDistancePct gte 800
						perfectPct gte 80
						perfectBonusPct gte 90
					*/
					if (stats.bonusCount gte 2) {
						stats.proposal = "Match";
						stats.description = "Multiple complex matches";
					} else if (stats.bonusCount eq 1 and stats.scoresPct gte 70 and stats.lcssDistancesPct gte 100 and stats.perfectsPct gte 60) {
						stats.proposal = "Match";
						stats.description = "Complex match plus scores";
					} else if (stats.scoresPct gte 90) {
						stats.proposal = "Match";
						stats.description = "High score";
					} else if (stats.lcssDistancesPct gte 800) {
						stats.proposal = "Match";
						stats.description = "High LCS/distance";
					} else if (stats.perfectsPct gte 80) {
						stats.proposal = "Match";
						stats.description = "Multiple perfect matches";
					} else if (stats.scoresPct gte 80 and stats.lcssDistancesPct gte 500 and stats.perfectsPct gte 70) {
						stats.proposal = "Match";
						stats.description = "High 3 point score";
					} else if (stats.bonusCount eq 0 and stats.scoresPct lt 40 and stats.lcssDistancesPct lt 60 and stats.perfectsPct lt 30) {
						stats.proposal = "Unmatch";
						stats.description = "No complex matches and low 3 point score";
					} else if (stats.perfectCount eq 0) {
						stats.proposal = "Unmatch";
						stats.description = "No perfect matches";
					} else {
						stats.proposal = "Review";
						stats.description = "Default condition";
					}
				}
				catch(any err) {
					writeDump(err);
					writeDump(var = compareResult, expand = "no");
				}
				newScore = base.scoreSimilarity(Replace(REReplace(UCase(Trim(Address)), "[^A-Z0-9]", "", "all"), "  ", " ", "all"), Replace(REReplace(UCase(Trim(Student_Address)), "[^A-Z0-9]", "", "all"), "  ", " ", "all"));
			</cfscript>
			<cfdump var="#newScore#" />
			<cfif client.gds.proposalValue eq stats.proposal or client.gds.proposalValue eq "All" and 1 eq 2>
				<cfoutput>
					<div id="gdsMatch_#GDS_ID#" class="row" style="display: none;">
						<div class="span2">
							<h4>Student</h4>
							<span class="highlighted">
								#result.first_name.string2# #result.last_name.string2#<br />
								#result.address.string2#<br />
								#result.city.string2#, CA #result.zip_code.string2#<br />
								#result.email.string2#<br />
								#result.phone.string2#<br />
								#result.dob.string2#<br />
								#result.ssn.string2#
							</span>
							<p class="recID">Student ID: #Student_ID#</p>
						</div>
						<div class="span2">
							<h4>GDS</h4>
							<span class="highlighted">
								#result.first_name.string1# #result.last_name.string1#<br />
								#result.address.string1#<br />
								#result.city.string1#, CA #result.zip_code.string1#<br />
								#result.email.string1#<br />
								#result.phone.string1#<br />
								#result.dob.string1#<br />
								#result.ssn.string1#
							</span>
							<p class="recID">GDS ID: #GDS_ID#</p>
						</div>
						<div class="span4">
							<table class="table table-bordered score-table"><!--- style="background-color: #IIf(proposalSource eq 'score' or proposalSource eq '4Point', DE('green'), DE('inherit'))#;" --->
								<!--- <tr>
									<th>Match Criteria Level</th>
									<td>#Match_Criteria#</td>
								</tr>
								<tr>
									<th>Score Count</th>
									<td>#stats.scoredCount#</td>
								</tr> --->
								<tr>
									<th>Similarity</th>
									<td>#Int(stats.scoresPct)#%</td>
								</tr>
								<tr>
									<th>Commonality</th>
									<td>XX</td>
								<tr>
									<th>Continuity</th>
									<td>#Int(stats.lcssDistancesPct)#%</td>
								</tr>
								<tr>
									<th nowrap="nowrap">Perfect+Complex Matches</th>
									<!--- <td>#DecimalFormat(stats.perfectsPct)#%</td> --->
									<td>#stats.perfectCount#+#stats.bonusCount# of #stats.scoredCount#</td>
								</tr>
								<!--- <tr>
									<th nowrap="nowrap">Complex Matches</th>
									<td>#stats.bonusCount#</td>
								</tr> --->
								<tr>
									<th>Propose</th>
									<td>#stats.proposal#</td>
								</tr>
								<tr>
									<th>Proposal Source</th>
									<td>#stats.description#</td>
								</tr>
								<tr>
									<td colspan="2">
										<cfif stats.proposal eq "Match">
											<a href="##" class="btn btn-danger btn-block" onclick="confirmUnmatch(#GDS_ID#); return false;">Unmatch</a>
										<cfelseif stats.proposal eq "Review">
											<a href="##" class="btn btn-warning btn-block" onclick="confirmUnmatch(#GDS_ID#); return false;">Unmatch</a>
										<cfelse>
											<a href="##" class="btn btn-success btn-block" onclick="unmatchGDS(#GDS_ID#); return false;">Unmatch</a>
										</cfif>
									</td>
								</tr>
							</table>
						</div>
						<div class="span4">
							<!--- <cfdump var="#compareResult.result#" expand="no" /> --->
							<table class="table table-bordered table-striped table-condensed stat-table">
								<thead>
									<tr>
										<th width="20%">Field</th>
										<th width="20%">Similarity</th>
										<th width="20%">Commonality</th>
										<th width="20%">Continuity</th>
										<th width="4%">L</th>
										<th width="4%">D</th>
										<th width="4%">ML</th>
										<th width="4%">P</th>
										<th width="4%">C</th>
										<!--- <th>Distance</th>
										<th>Max Len</th> --->
									</tr>
								</thead>
								<tbody>
									<cfset fields = StructKeyList(result) />
									<cfset fields = ListSort(fields, "TextNoCase") />
									<cfloop index="prop" list="#fields#">
										<cfset perfectMatch = false />
										<cfset complexMatch = false />
										<cfset scorePct = result[prop].score * 100 />
										<cfif result[prop].distance gt 0>
											<cfset lcsDistancePct = result[prop].lcs/result[prop].distance * 100 />
										<cfelseif result[prop].lcs gt 0>
											<cfset lcsDistancePct = 100 />
											<cfset perfectMatch = true />
											<cfif prop eq "address" or prop eq "email" or prop eq "phone">
												<cfset complexMatch = true />
											</cfif>
										<cfelse>
											<cfset lcsDistance = 0 />
										</cfif>
										<cfif result[prop].maxLen gt 0>
											<cfset lcsMaxLenPct = result[prop].lcs/result[prop].maxLen * 100 />
										<cfelse>
											<cfset lcsMaxLenPct = 0 />
										</cfif>
										<tr>
											<td>#prop#</td>
											<td>#Int(scorePct)#%</td>
											<td>#Int(lcsMaxLenPct)#%</td>
											<td>#Int(lcsDistancePct)#%</td>
											<td>#Int(result[prop].lcs)#</td>
											<td>#Int(result[prop].distance)#</td>
											<td>#Int(result[prop].maxLen)#</td>
											<td>#Left(YesNoFormat(perfectMatch), 1)#</td>
											<td>#Left(YesNoFormat(complexMatch), 1)#</td>
											<!--- <td>#result[prop].distance#</td>
											<td>#result[prop].maxLen#</td> --->
											<!--- <td>#result[prop].distance#</td>
											<td>#compareResult.config[prop].maxOffset#</td> --->
										</tr>
									</cfloop>
								</tbody>
							</table>
						</div>
					</div>
				</cfoutput>
				<cfset displayedCount = displayedCount + 1 />
				<cfif displayedCount gte 20>
					<cfbreak />
				</cfif>
			</cfif>
		</cfloop>
	</div>
	<!--- <cfdump var="#compareResult#" /> --->
<cfelse>

	<div class="alert alert-info notFound">No GDS records</div>

	<script type="text/javascript" language="javascript">
	<!--
		$(function() {
			$("#filter").show();
		});
	// -->
	</script>
	
</cfif>


<!---<cfloop index="prop" list="#propList#">
					<cfif IsStruct(compareResult.result[prop])>
						<cfif Len(compareResult.result[prop].string1) gt 0 and Len(compareResult.result[prop].string2) gt 0>
							<cfset totalScore = totalScore + compareResult.result[prop].score />
							<cfset maxScore = maxScore + 1 />
							<cfset pct = compareResult.result[prop].score * 100 />
							<cfset totalMultipliers = totalMultipliers + compareResult.config[prop].multiplier />
							<cfset weightedScore = compareResult.result[prop].score * compareResult.config[prop].multiplier />
							<cfset totalWeightedScore = totalWeightedScore + weightedScore />
							<cfset maxWeightedScore = maxWeightedScore + compareResult.config[prop].multiplier />
							<cfset weightedPCT = weightedScore/compareResult.config[prop].multiplier * 100 />
							<cfset totalOffsets = totalOffsets + compareResult.config[prop].maxOffset />
							<cfset totalLCS = totalLCS + compareResult.result[prop].lcs/>
							<cfset totalDistance = totalDistance + compareResult.result[prop].distance />
							<cfif pct eq 100>
								<cfset perfectScores = perfectScores + 1>
							</cfif>
							<cfset scoreCount = scoreCount + 1 />
							<!--- <cfif compareResult.result[prop].lcs eq 0>
								<cfset lcsDistance = 0 />
							<cfelseif compareResult.result[prop].distance eq 0>
								<cfset lcsDistance = 100 />
							<cfelse>
								<cfset lcsDistance = compareResult.result[prop].lcs/compareResult.result[prop].distance * 100 />
							</cfif> --->
						</cfif>
						<tr>
							<!--- <cfif prop eq ListFirst(propList)>
								<cfset rowspan = ListLen(propList) /> --->
								<td>
									#compareResult.result.first_name.string1# #compareResult.result.last_name.string1#<br />
									#compareResult.result.address.string1#<br />
									#compareResult.result.city.string1#, CA #compareResult.result.zip_code.string1#<br />
									#compareResult.result.email.string1#<br />
									<!--- #compareResult.result.phone1.string1#<br />
									#compareResult.result.phone2.string1#<br /> --->
									#compareResult.result.dob.string1#<br />
									#compareResult.result.ssn.string1#
								</td>
								<td>
									#compareResult.result.first_name.string2# #compareResult.result.last_name.string2#<br />
									#compareResult.result.address.string2#<br />
									#compareResult.result.city.string2#, CA #compareResult.result.zip_code.string2#<br />
									#compareResult.result.email.string2#<br />
									<!--- #compareResult.result.phone1.string2#<br />
									#compareResult.result.phone2.string2#<br /> --->
									#compareResult.result.dob.string2#<br />
									#compareResult.result.ssn.string2#
								</td>
								<td>
									<h2>Score</h2>
									<a href="?action=rejectGDS&view=#view#&GDS_ID=#GDS_ID#" class="btn btn-warning">Unmatch</a>
								</td>
							<!--- </cfif> --->
							<!--- <td>#Round(pct)#%</td> --->
							<cfif showStats>
								<td>
									<table>
										<tr>
											<th class="statcol">Property</th>
											<th class="statcol">Score</th>
											<th class="statcol">Max Offset</th>
											<th class="statcol">LCS</th>
											<th class="statcol">Distance</th>
										</tr>
										<tr>
											<td>#prop#</td>
											<cfif Len(compareResult.result[prop].string1) gt 0 and Len(compareResult.result[prop].string2) gt 0>
												<td>#compareResult.result[prop].score#</td>
												<td>#Int(compareResult.config[prop].maxOffset)#</td>
												<td>#Int(compareResult.result[prop].lcs)#</td>
												<td>#Int(compareResult.result[prop].distance)#</td>
											<cfelse>
												<td colspan="4" style="text-align: center;">N/A</td>
											</cfif>
										</tr>
									</table>
								</td>
							</cfif>
						</tr>
					</cfif>
				</cfloop>

				<!--- <cfset totalPCT = totalScore/maxScore * 100 />
				<cfset totalWeightedPCT = totalWeightedScore/maxWeightedScore * 100 />
				<cfset totalLCSDistance = totalLCS/totalDistance />
				<cfset multiFactorScore = totalPCT * totalLCSDistance />
				<cfif multiFactorScore lt 20>
					<cfset bgColor = "red" />
				<cfelseif multiFactorScore lt 100>
					<cfset bgColor = "orange">
				<cfelse>
					<cfset bgColor = "green" />
				</cfif>
				<cfset perfectScorePCT = perfectScores / scoreCount * 100 />
				<tr style="background-color: #bgColor#; color: white; font-weight: bold;">
					<td colspan="2"></td>
					<td>#DecimalFormat(multiFactorScore)# / #perfectScorePCT#%</td>
					<!--- <td>#Round(totalPCT)#%</td> --->
					<cfif showStats>
						<td></td>
						<td>#Round(totalPCT)#%</td>
						<!--- <td>#totalMultipliers#</td>
						<td>#Round(totalWeightedPCT)#%</td>
						<td>#totalOffsets#</td> --->
						<td>#totalLCS#</td>
						<td>#totalDistance#</td>
						<!--- <td></td> --->
					</cfif>
					
				</tr> --->
				
--->

<!--- <table class="table">
		<thead>
			<tr>
				<th>First Name</th>
				<th>Last Name</th>
				<th>Full Name</th>
				<th>Address</th>
				<th>City</th>
				<th>Zip Code</th>
				<th>Phone 1</th>
				<th>Phone 2</th>
				<th>E-mail</th>
				<th>SSN</th>
				<th>DOB</th>
				<th class="action"></th>
			</tr>
		</thead>
		<tbody> --->
		<!--- <cfset firstNameFactor = 2 />
		<cfset lastNameFactor = 4 />
		<cfset fullNameFactor = 5 />
		<cfset addressFactor = 4 />
		<cfset cityFactor = 2 />
		<cfset zipCodeFactor = 1 />
		<cfset phone1Factor = 5 />
		<cfset phone2Factor = 5 />
		<cfset phoneFactor = 5 />
		<cfset emailFactor = 5 />
		<cfset ssnFactor = 2 />
		<cfset dobFactor = 1 />
		<cfset sumOfFactors = 0 />
		<cfset availableSum = 0 />
		<cfset totalScore = 0 /> --->			
<!--- old algorithm <cfset gdsFirstName = UCase(REReplace(First_Name, "[^a-zA-Z0-9] ","","all")) />
				<cfset cfcFirstName = UCase(REReplace(Student_First_Name, "[^a-zA-Z0-9] ","","all")) />
				<cfif Len(gdsFirstName) gt 0 and Len(cfcFirstName) gt 0>
					<cfset compFirstName = stringSimilarity(UCase(gdsFirstName), UCase(cfcFirstName), 5) />
					<cfset firstNameSimilarity = compFirstName.similarity />
					<cfset firstNameScore = firstNameSimilarity * firstNameFactor />
					<cfset sumOfFactors = sumOfFactors + firstNameFactor />
				<cfelse>
					<cfset compFirstName = "" />
					<cfset firstNameSimilarity = 0 />
					<cfset firstNameScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + firstNameScore />
				
				<cfset gdsLastName = UCase(REReplace(Last_Name, "[^a-zA-Z0-9 ]","","all")) />
				<cfset cfcLastName = UCase(REReplace(Student_Last_Name, "[^a-zA-Z0-9 ]","","all")) />
				<cfif Len(gdsLastName) gt 0 and Len(cfcLastName) gt 0>
					<cfset compLastName = stringSimilarity(UCase(gdsLastName), UCase(cfcLastName), 5) />
					<cfset lastNameSimilarity = compLastName.similarity />
					<cfset lastNameScore = lastNameSimilarity * lastNameFactor />
					<cfset sumOfFactors = sumOfFactors + lastNameFactor />
				<cfelse>
					<cfset compLastName = "" />
					<cfset lastNameSimilarity = 0 />
					<cfset lastNameScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + lastNameScore />
				
				<cfset gdsFullName = gdsFirstName & gdsLastName />
				<cfset cfcFullName = cfcFirstName & cfcLastName />
				<cfif Len(gdsFirstName) gt 0 and Len(cfcFirstName) gt 0 and Len(gdsLastName) gt 0 and Len(cfcLastName) gt 0>
					<cfset compFullName = stringSimilarity(UCase(gdsFullName), UCase(cfcFullName), 7) />
					<cfset fullNameSimilarity = compFullName.similarity />
					<cfset fullNameScore = fullNameSimilarity * fullNameFactor />
					<cfset sumOfFactors = sumOfFactors + fullNameFactor />
				<cfelse>
					<cfset compFullName = "" />
					<cfset fullNameSimilarity = 0 />
					<cfset fullNameScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + fullNameScore />
				
				<cfset gdsAddress = UCase(REReplace(Address, "[^a-zA-Z0-9 ]","","all")) />
				<cfset cfcAddress = UCase(REReplace(Student_Address, "[^a-zA-Z0-9 ]","","all")) />
				<cfif Len(gdsAddress) gt 0 and Len(cfcAddress) gt 0>
					<cfset compAddress = stringSimilarity(UCase(gdsAddress), UCase(cfcAddress), 6) />
					<cfset addressSimilarity = compAddress.similarity />
					<cfset addressScore = addressSimilarity * addressFactor />
					<cfset sumOfFactors = sumOfFactors + addressFactor />
				<cfelse>
					<cfset compAddress = "" />
					<cfset addressSimilarity = 0 />
					<cfset addressScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + addressScore />
				
				<cfset gdsCity = UCase(REReplace(City, "[^a-zA-Z0-9 ]","","all")) />
				<cfset cfcCity = UCase(REReplace(Student_City, "[^a-zA-Z0-9 ]","","all")) />
				<cfif Len(gdsAddress) gt 0 and Len(cfcAddress) gt 0>
					<cfset compCity = stringSimilarity(UCase(gdsCity), UCase(cfcCity), 5) />
					<cfset citySimilarity = compCity.similarity />
					<cfset cityScore = citySimilarity * cityFactor />
					<cfset sumOfFactors = sumOfFactors + cityFactor />
				<cfelse>
					<cfset compCity = "" />
					<cfset citySimilarity = 0 />
					<cfset cityScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + cityScore />
				
				<cfset gdsZipCode = Right(REReplace(Zip_Code, "[^0-9]","","all"), 5) />
				<cfset cfcZipCode = Right(REReplace(Student_Zip_Code, "[^0-9]","","all"), 5) />
				<cfif Len(gdsZipCode) gt 0 and Len(cfcZipCode) gt 0>
					<cfset compZipCode = stringSimilarity(UCase(gdsZipCode), UCase(cfcZipCode), 1) />
					<cfset zipCodeSimilarity = compZipCode.similarity />
					<cfset zipCodeScore = zipCodeSimilarity * zipCodeFactor />
					<cfset sumOfFactors = sumOfFactors + zipCodeFactor />
				<cfelse>
					<cfset compZipCode = "" />
					<cfset zipCodeSimilarity = 0 />
					<cfset zipCodeScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + zipCodeScore />
				
				<cfset gdsPhone = REReplace(Phone, "[^0-9]","","all") />
				<cfset cfcPhone1 = REReplace(Student_Phone1, "[^0-9]","","all") />
				<cfset cfcPhone2 = REReplace(Student_Phone2, "[^0-9]","","all") />
				<cfif Len(gdsPhone) gt 0 and Len(cfcPhone1) gt 0>
					<cfset compPhone1 = stringSimilarity(gdsPhone, cfcPhone1, 2) />
					<cfset phone1Similarity = compPhone1.similarity />
					<cfset phone1Score = phone1Similarity * phoneFactor />
					<!--- <cfset sumOfFactors = sumOfFactors + phone1Factor /> --->
				<cfelse>
					<cfset compPhone1 = "" />
					<cfset phone1Similarity = 0 />
					<cfset phone1Score = 0 />
				</cfif>
				<!--- <cfset totalScore = totalScore + phone1Score /> --->
				
				<cfif Len(gdsPhone) gt 0 and Len(cfcPhone2) gt 0>
					<cfset compPhone2 = stringSimilarity(gdsPhone, cfcPhone2, 3) />
					<cfset phone2Similarity = compPhone2.similarity />
					<cfset phone2Score = phone2Similarity * phoneFactor />
					<!--- <cfset sumOfFactors = sumOfFactors + phone2Factor /> --->
				<cfelse>
					<cfset compPhone2 = "" />
					<cfset phone2Similarity = 0 />
					<cfset phone2Score = 0 />
				</cfif>
				<!--- <cfset totalScore = totalScore + phone2Score /> --->
				<cfif phone1Score gt phone2Score>
					<cfset phoneSimilarity = phone1Similarity />
					<cfset phoneScore = phone1Score />
					<cfset sumOfFactors = sumOfFactors + phoneFactor />
					<cfset totalScore = totalScore + phone1Score />
				<cfelse>
					<cfset phoneSimilarity = phone2Similarity />
					<cfset phoneScore = phone2Score />
					<cfset sumOfFactors = sumOfFactors + phoneFactor />
					<cfset totalScore = totalScore + phone2Score />
				</cfif>
				
				<cfset gdsEmail = REReplace(Stdt_Email_Addr, "[^a-zA-Z0-9]","","all") />
				<cfset cfcEmail = REReplace(Student_Email, "[^a-zA-Z0-9]","","all") />
				<cfif Len(gdsEmail) gt 0 and Len(cfcEmail) gt 0>
					<cfset compEmail = stringSimilarity(UCase(gdsEmail), UCase(cfcEmail), 5) />
					<cfset emailSimilarity = compEmail.similarity />
					<cfset emailScore = emailSimilarity * emailFactor />
					<cfset sumOfFactors = sumOfFactors + emailFactor />
				<cfelse>
					<cfset compEmail = "" />
					<cfset emailSimilarity = 0 />
					<cfset emailScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + emailScore />
				
				<cfset gdsSSN = Right(REReplace(SSN, "[^a-zA-Z0-9]","","all"), 4) />
				<cfset cfcSSN = Right(REReplace(Student_SSN, "[^a-zA-Z0-9]","","all"), 4) />
				<cfif Len(gdsSSN) gt 0 and Len(cfcSSN) gt 0>
					<cfset compSSN = stringSimilarity(gdsSSN, cfcSSN, 1) />
					<cfset ssnSimilarity = compSSN.similarity />
					<cfset ssnScore = ssnSimilarity * ssnFactor />
					<cfset sumOfFactors = sumOfFactors + ssnFactor />
				<cfelse>
					<cfset compSSN = "" />
					<cfset ssnSimilarity = 0 />
					<cfset ssnScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + ssnScore />
				
				<cfset gdsDOB = DateFormat(DOB, "yyyymmdd") />
				<cfset cfcDOB = DateFormat(Student_DOB, "yyyymmdd") />
				<cfif Len(gdsDOB) gt 0 and Len(cfcDOB) gt 0>
					<cfset compDOB = stringSimilarity(gdsDOB, cfcDOB, 1) />
					<cfset dobSimilarity = compDOB.similarity />
					<cfset dobScore = dobSimilarity * dobFactor />
					<cfset sumOfFactors = sumOfFactors + dobFactor />
				<cfelse>
					<cfset compDOB = "" />
					<cfset dobSimilarity = 0 />
					<cfset dobScore = 0 />
				</cfif>
				<cfset totalScore = totalScore + dobScore />--->
<!--- <tr>
									<td width="250">#base.titleCase(First_Name)#</td>
									<td width="250">#base.titleCase(Student_First_Name)#</td>
									<td width="150">#DecimalFormat(firstNameSimilarity)#</td>
									<td width="150">#DecimalFormat(firstNameFactor)#</td>
									<td width="150">#DecimalFormat(firstNameScore)#</td>
								</tr>
								<tr>
									<td>#base.titleCase(Last_Name)#</td>
									<td>#base.titleCase(Student_Last_Name)#</td>
									<td>#DecimalFormat(lastNameSimilarity)#</td>
									<td>#DecimalFormat(lastNameFactor)#</td>
									<td>#DecimalFormat(lastNameScore)#</td>
								</tr>
								<tr>
									<td>#base.titleCase(First_Name)# #base.titleCase(Last_Name)#</td>
									<td>#base.titleCase(Student_First_Name)# #base.titleCase(Student_Last_Name)#</td>
									<td>#DecimalFormat(fullNameSimilarity)#</td>
									<td>#DecimalFormat(fullNameFactor)#</td>
									<td>#DecimalFormat(fullNameScore)#</td>
								</tr>
								<tr>
									<td>#base.titleCase(Address)#</td>
									<td>#base.titleCase(Student_Address)#</td>
									<td>#DecimalFormat(addressSimilarity)#</td>
									<td>#DecimalFormat(addressFactor)#</td>
									<td>#DecimalFormat(addressScore)#</td>
								</tr>
								<tr>
									<td>#base.titleCase(City)#</td>
									<td>#base.titleCase(Student_City)#</td>
									<td>#DecimalFormat(citySimilarity)#</td>
									<td>#DecimalFormat(cityFactor)#</td>
									<td>#DecimalFormat(cityScore)#</td>
								</tr>
								<tr>
									<td>#Zip_Code#</td>
									<td>#Student_Zip_Code#</td>
									<td>#DecimalFormat(zipCodeSimilarity)#</td>
									<td>#DecimalFormat(zipCodeFactor)#</td>
									<td>#DecimalFormat(zipCodeScore)#</td>
								</tr>
								
								<tr>
									<td>#base.formatPhone(Phone)#</td>
									<td>
									<cfif phone1Score gt phone2Score>
										#base.formatPhone(Student_Phone1)#
									<cfelse>
										#base.formatPhone(Student_Phone2)#
									</cfif>
									</td>
									<td>#DecimalFormat(phoneSimilarity)#</td>
									<td>#DecimalFormat(phoneFactor)#</td>
									<td>#DecimalFormat(phoneScore)#</td>
								</tr>
								<tr>
									<td>#LCase(Stdt_Email_Addr)#</td>
									<td>#LCase(Student_Email)#</td>
									<td>#DecimalFormat(emailSimilarity)#</td>
									<td>#DecimalFormat(emailFactor)#</td>
									<td>#DecimalFormat(emailScore)#</td>
								</tr>
								<tr>
									<td>#SSN#</td>
									<td>#Student_SSN#</td>
									<td>#DecimalFormat(ssnSimilarity)#</td>
									<td>#DecimalFormat(ssnFactor)#</td>
									<td>#DecimalFormat(ssnScore)#</td>
								</tr>
								<tr>
									<td>#DateFormat(DOB, "m/d/yyyy")#</td>
									<td>#DateFormat(Student_DOB, "m/d/yyyy")#</td>
									<td>#DecimalFormat(dobSimilarity)#</td>
									<td>#DecimalFormat(dobFactor)#</td>
									<td>#DecimalFormat(dobScore)#</td>
								</tr> --->
<!--- <script type="text/javascript">
		
		var parseQuestions = function(questions) {
			for (var q = 0; q < questions.length; q++) {
				questions[q].QUESTION_NUMBER = parseInt(questions[q].QUESTION_NUMBER);
				questions[q].RESPONSE_COUNT = parseInt(questions[q].RESPONSE_COUNT);
				questions[q].MULTI_RESPONSE_COUNT = parseInt(questions[q].MULTI_RESPONSE_COUNT);
				questions[q].NO_RESPONSE_COUNT = parseInt(questions[q].NO_RESPONSE_COUNT);
			}
			return questions;
		}
		
		var parseAnswers = function(answers) {
			for (var a = 0; a < answers.length; a++) {
				if (answers[a].ANSWER === true) {
					answers[a].ANSWER = "Yes ";
				} else if (answers[a].ANSWER === false) {
					answers[a].ANSWER = "No ";
				}
				answers[a].ANSWER_NUMBER = parseInt(answers[a].ANSWER_NUMBER);

				answers[a].RESPONSE_COUNT = parseInt(answers[a].RESPONSE_COUNT);
				answers[a].RESPONSE_PERCENT = parseFloat(answers[a].RESPONSE_PERCENT);
				//answers[a].RESPONSE_OTHER = answers[a].ANSWER_VALUES.toString();
				answers[a].EXPLODE = false;
			}
			return answers;
		}

		<cfoutput>
			var questions = #SerializeJSON(evaluations)#;
		</cfoutput>
		
		var pieLabelTemplate = "#= dataItem.ANSWER# - #= dataItem.RESPONSE_PERCENT#%";
		var pieLegendTemplate = "#= dataItem.ANSWER# - #= dataItem.RESPONSE_PERCENT#%";
		//var pieTooltipTemplate = "#= dataItem.ANSWER# - #= dataItem.RESPONSE_COUNT#";
		var pieTooltipTemplate = "#= dataItem.RESPONSE_COUNT# responses = #= dataItem.RESPONSE_PERCENT#%";
		var barLabelTemplate = "#= dataItem.ANSWER# - #= dataItem.RESPONSE_PERCENT#%";
		var barLegendTemplate = "#= text#";
		var barTooltipTemplate = "#= dataItem.RESPONSE_COUNT# responses = #= dataItem.RESPONSE_PERCENT#%";
		var labelFont = "12px Arial,Helvetical,sans-serif";
		var legendFont = "12px Arial,Helvetical,sans-serif";
		var tooltipFont = "12px Arial,Helvetical,sans-serif";
		
		renderPieChart = function(q) {
			var question = questions[q-1];
			var answers = parseAnswers(question.ANSWERS);
			$("#q" + q + "Chart").kendoChart({
				theme: $(document).data("kendoSkin") || "metro",
				dataSource: answers,
				series: [{
					type: "pie",
					field: "RESPONSE_PERCENT",
					categoryField: "ANSWER",
					explodeField: "EXPLODE",
					labels: {
						visible: true,
						align: "circle",
						font: labelFont,
						template: pieLabelTemplate,
						distance: 20
					},
					padding: 50
				}],
				legend: {
					visible: false,
					position: "left",
					labels: {
						font: legendFont,
						template: pieLegendTemplate
					}
				},
				tooltip: {
					visible: true,
					font: tooltipFont,
					template: pieTooltipTemplate
				}
			})
		}
		
		renderBarChart = function(q) {
			var question = questions[q-1];
			var answers = parseAnswers(question.ANSWERS);
			$("#q" + q + "Chart").kendoChart({
				theme: $(document).data("kendoSkin") || "metro",
				dataSource: answers,
				plotArea: {
					margin: {
						right: 200
					}
				},
				series: [{
					type: "bar",
					field: "RESPONSE_PERCENT",
					categoryField: "ANSWER",
					labels: {visible: true, font: labelFont, template: barLabelTemplate, position: "outsideEnd"},
					missingValue: "zero",
					gap: 0.4,
					spacing: 0.2,
					markers: {visible: true, border: {width: 2, size: 6}},
					padding: 50
				}],
				valueAxis: {
					title: {visible: false, text: "valueAxis"},
					labels: {template: "#= value#%"},
					majorGridLines: {visible: true, color: "gray"},
					majorTicks: {visible: true, color: "gray"},
					minorGridLines: {visible: false, color: "silver"},
					minorTicks: {visible: false, color: "silver"},
					plotBands: [{
						from: 49,
						to: 51,
						color: "gray",
						opacity: 0.3
					}]
				},
				categoryAxis: {
					title: {visible: false, text: "categoryAxis"},
					majorGridLines: {visible: false},
					majorTicks: {visible: false}
				},
				legend: {
					visible: false,
					position: "left",
					labels: {font: legendFont, template: barLegendTemplate}
				},
				tooltip: {
					visible: true,
					font: tooltipFont,
					template: barTooltipTemplate
				}
			})
		}

		$(function() {
			var pieCharts = "1,2,3,4,5,7,10,11,13,15,17,19";
			var barCharts = "6,9,12,14,16,18";
			var pieChartsArray = pieCharts.split(",");
			var barChartsArray = barCharts.split(",");
			if (pieChartsArray.length > 0) {
				for (var q = 0; q < pieChartsArray.length; q++) {
					renderPieChart(pieChartsArray[q]);
				}
			}
			if (barChartsArray.length > 0) {
				for (var q = 0; q < barChartsArray.length; q++) {
					renderBarChart(barChartsArray[q]);
				}
			}
		})
	
	</script>
	<style type="text/css">
		.k-chart {
			width: 800px;
			height: 400px;
		}
	</style>

	<cfoutput>

		<div class="accordion" id="esAccordian">

			<cfloop index="q" from="1" to="#ArrayLen(evaluations)#">
				<cfset totalExitSurveys = evaluations[q].Response_Count + evaluations[q].No_Response_Count />
				<cfset noResponsePercent = evaluations[q].No_Response_Count / totalExitSurveys * 100 />
				<cfset multiResponsePercent = evaluations[q].Multi_Response_Count / totalExitSurveys * 100 />
				<div class="accordion-group">
					<div class="accordion-heading"> <a class="accordion-toggle" data-toggle="collapse" data-parent="##esAccordian" href="##p#q#">#q#. #evaluations[q].Question#</a> </div>
					<div id="p#q#" class="accordion-body collapse<cfif q eq 1> in</cfif>">
						<div class="accordion-inner">
							<cfif q eq 8>
								Data can not be charted. 
							<cfelse>
								<ul class="nav nav-pills">
									<li class="active"><a href="##table#q#" data-toggle="pill">Table</a></li>
									<li><a href="##chart#q#" data-toggle="pill">Chart</a></li>
								</ul>
								<div class="tab-content">
									<div class="tab-pane active" id="table#q#">
										<table class="table table-hover table-bordered">
											<thead>
												<th>Answer</th>
												<th>Count</th>
												<th>Percent</th>
											</thead>
											<tbody>
												<cfloop index="a" from="1" to="#ArrayLen(evaluations[q].Answers)#">
													<tr>
														<td>#evaluations[q].Answers[a].Answer#</td>
														<td>#evaluations[q].Answers[a].Response_Count#</td>
														<td>#evaluations[q].Answers[a].Response_Percent#%</td>
													</tr>
												</cfloop>
												<tr>
													<td>Did not respond</td>
													<td>#evaluations[q].No_Response_Count#</td>
													<td>#DecimalFormat(noResponsePercent)#%</td>
												</tr>
												<cfif evaluations[q].Question_Type eq "Multiple select">
													<tr>
														<td>Multiple responses</td>
														<td>#evaluations[q].Multi_Response_Count#</td>
														<td>#DecimalFormat(multiResponsePercent)#%</td>
													</tr>
												</cfif>
											</tbody>
										</table>
									</div>
									<div class="tab-pane" id="chart#q#">
										<div id="q#q#Chart"></div>
									</div>
								</div>
							</cfif>
						</div>
					</div>
				</div>
			</cfloop>
		</div>
	
	</cfoutput> --->
<!--- <tr>
	<td colspan="12">
	
		<table>
			<tr>
				<td width="50%">
					#base.titleCase(First_Name)# #base.titleCase(Last_Name)#<br />
					#base.titleCase(Address)#<br />
					#base.titleCase(City)#, CA #Zip_Code#<br />
					#base.formatPhone(Phone)#<br />
					#LCase(Stdt_Email_Addr)#<br />
					#SSN#<br />
					#DateFormat(DOB, "m/d/yyyy")#
				</td>
				<td width="50%">
					#base.titleCase(Student_First_Name)# #base.titleCase(Student_Last_Name)#<br />
					#base.titleCase(Student_Address)#<br />
					#base.titleCase(Student_City)#, CA #Student_Zip_Code#<br />
					<cfif Len(Trim(Student_Phone2)) gt 0 and compPhone2.similarity gt compPhone1.similarity>
						#base.formatPhone(Student_Phone2)#<br />
					<cfelseif Len(Trim(Student_Phone1)) gt 0>
						#base.formatPhone(Student_Phone1)#<br />
					</cfif>
					#LCase(Student_Email)#<br />
					#Student_SSN#<br />
					#DateFormat(Student_DOB, "m/d/yyyy")#
				</td>
			</tr>
		</table>
		
	</td>
</tr>	
<tr>
	<td>#base.titleCase(First_Name)#</td>
	<td>#base.titleCase(Last_Name)#</td>
	<td>#base.titleCase(First_Name)# #base.titleCase(Last_Name)#</td>
	<td>#base.titleCase(Address)#</td>
	<td>#base.titleCase(City)#</td>
	<td>#Zip_Code#</td>
	<td>#base.formatPhone(Phone)#</td>
	<td>#base.formatPhone(Phone)#</td>
	<td>#LCase(Stdt_Email_Addr)#</td>
	<td>#SSN#</td>
	<td>#DateFormat(DOB, "m/d/yyyy")#</td>
	<td></td>
</tr>
<tr>
	<td>#base.titleCase(Student_First_Name)#</td>
	<td>#base.titleCase(Student_Last_Name)#</td>
	<td>#base.titleCase(Student_First_Name)# #base.titleCase(Student_Last_Name)#</td>
	<td>#base.titleCase(Student_Address)#</td>
	<td>#base.titleCase(Student_City)#</td>
	<td>#Student_Zip_Code#</td>
	<td>#base.formatPhone(Student_Phone1)#</td>
	<td>#base.formatPhone(Student_Phone2)#</td>
	<td>#LCase(Student_Email)#</td>
	<td>#Student_SSN#</td>
	<td>#DateFormat(Student_DOB, "m/d/yyyy")#</td>
	<td></td>
</tr>
<tr>
	<td>#DecimalFormat(compFirstName.similarity)#</td>
	<td>#DecimalFormat(compLastName.similarity)#</td>
	<td>#DecimalFormat(compFullName.similarity)#</td>
	<td>#DecimalFormat(compAddress.similarity)#</td>
	<td>#DecimalFormat(compCity.similarity)#</td>
	<td>#DecimalFormat(compZipCode.similarity)#</td>
	<td>#DecimalFormat(compPhone1.similarity)#</td>
	<td>#DecimalFormat(compPhone2.similarity)#</td>
	<td>#DecimalFormat(compEmail.similarity)#</td>
	<td>#DecimalFormat(compSSN.similarity)#</td>
	<td>#DecimalFormat(compDOB.similarity)#</td>
	<td></td>
</tr> --->